#ifndef 线性表测试
#define 线性表测试

#include "单链表.h"
#include "顺序表.h"
#include <catch2.hpp>

TEST_CASE("顺序表")
{
    SECTION("插入元素")
    {
        SqList L;
        L.length = 0;
        REQUIRE(ListInsert(L, 1, 10) == true);
        REQUIRE(L.data[0] == 10);
        REQUIRE(L.length == 1);

        REQUIRE(ListInsert(L, 2, 20) == true);
        REQUIRE(L.data[1] == 20);
        REQUIRE(L.length == 2);

        REQUIRE(ListInsert(L, 4, 30) == false);
    }

    SECTION("输出元素")
    {
        SqList L;
        L.length = 3;
        L.data[0] = 10;
        L.data[1] = 20;
        L.data[2] = 30;

        ElemType e;
        REQUIRE(ListDelete(L, 2, e) == true);
        REQUIRE(e == 20);
        REQUIRE(L.length == 2);
        REQUIRE(L.data[0] == 10);
        REQUIRE(L.data[1] == 30);

        REQUIRE(ListDelete(L, 4, e) == false);
    }

    SECTION("查找元素")
    {
        SqList L;
        L.length = 3;
        L.data[0] = 10;
        L.data[1] = 20;
        L.data[2] = 30;

        REQUIRE(LocateElem(L, 10) == 1);
        REQUIRE(LocateElem(L, 20) == 2);
        REQUIRE(LocateElem(L, 30) == 3);
        REQUIRE(LocateElem(L, 40) == 0);
    }
}

TEST_CASE("单链表")
{
    int Llen = 10;
    LinkList headH = nullptr;
    LinkList headT = nullptr;

    std::string example = "10 9 8 7 6 5 4 3 2 1 9999";
    int expected_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    List_HeadInsert(headH, example);
    List_TailInsert(headT, example);

    SECTION("长度")
    {
        REQUIRE(Length(headH) == Llen);
        REQUIRE(Length(headT) == Llen);
    }

    SECTION("头插法")
    {
        LNode *p = headH->next;
        for (int i = 0; i < headH->data; ++i)
        {
            REQUIRE(p->data == expected_data[i]);
            p = p->next;
        }
    }

    SECTION("尾插法")
    {
        LNode *p = headT->next;
        for (int i = headT->data - 1; i >= 0; --i)
        {
            REQUIRE(p->data == expected_data[i]);
            p = p->next;
        }
    }

    SECTION("按序号查找结点")
    {
        REQUIRE(GetElem(headH, 3) == headH->next->next->next);
        REQUIRE(GetElem(headH, 1)->data == 1);
        REQUIRE(GetElem(headH, 10)->data == 10);

        REQUIRE(GetElem(headT, 3) == headT->next->next->next);
        REQUIRE(GetElem(headH, 1)->data == 1);
        REQUIRE(GetElem(headH, 10)->data == 10);

        REQUIRE(GetElem(headH, 0) == nullptr);
        REQUIRE(GetElem(headH, 11) == nullptr);
    }

    SECTION("按值查找结点")
    {
        REQUIRE(LocateElem(headH, 0) == nullptr);
        REQUIRE(LocateElem(headH, 1) == headH->next);
        REQUIRE(LocateElem(headH, 8)->data == 8);
        REQUIRE(LocateElem(headH, 10) == headH->next->next->next->next->next->next->next->next->next->next);

        REQUIRE(LocateElem(headT, 0) == nullptr);
        REQUIRE(LocateElem(headT, 10) == headT->next);
        REQUIRE(LocateElem(headT, 1) == headT->next->next->next->next->next->next->next->next->next->next);
    }

    SECTION("插入")
    {
        REQUIRE(GetElem(headH, 0) == nullptr);
        REQUIRE(GetElem(headH, 100) == nullptr);
        REQUIRE(Length(headH) == Llen);

        ListInsert(headH, 1, 0);
        ListInsert(headH, 12, 12);
        REQUIRE(Length(headH) == (Llen += 2));
        REQUIRE(GetElem(headH, 1)->data == 0);
        REQUIRE(GetElem(headH, 12)->data == 12);
        ListInsert(headH, 7, 99);
        REQUIRE(Length(headH) == (Llen += 1));
        REQUIRE(GetElem(headH, 7)->data == 99);
    }

    SECTION("删除")
    {
        ListDelete(headH, 10);
        REQUIRE(Length(headH) == (--Llen));

        LNode *p1 = headH->next->next;
        REQUIRE(ListDelete(headH, 1) == p1);
        REQUIRE(Length(headH) == (--Llen));

        REQUIRE(ListDelete(headH, 0) == nullptr);
    }
}

#endif